/**
 * 
 */
package com.cfweb.controller.alert;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cfweb.controller.BasicInfo;
import com.cfweb.controller.LoginHandler;
import com.cfweb.dao.CfAppMapper;
import com.cfweb.domain.CfApp;
import com.cfweb.domain.CfAppExample;
import com.cfweb.exception.CloudFoundryApiException;
import com.cfweb.util.CloudFoundryClientUtil;
import com.cfweb.util.JsonUtil;
import com.cfweb.util.MailUtil;

/**   
* @Title: AlertManagement.java 
* @Package com.cfweb.controller.alert 
* @Description:  进行监控预警
* @author 龙立强   
* @date 2016年1月13日 下午8:58:58 
* @version V1.0   
*/

@Service
@Path("/alert")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class AlertManagement {

	Logger logger = Logger.getLogger(BasicInfo.class);

	@Autowired  
	private HttpSession session; 

	@Autowired
	private CfAppMapper caMapper;
	
	private final int APPSTATE = 3;
	
	/***
	 * 监控预警
	 * 预警规则：遍历所有应用，遍历应用的所有实例，在连续五次的请求中都存在超过阈值的情况下才会提出预警
	 * @return
	 * @throws Exception
	 */
	@Path("/appMonitAlert")
	@GET
	public List<Map<String, String>> appMonitAlert() throws Exception {
		
		List< Map<String, String> > returnList = new ArrayList<Map<String, String>>(); //最终返回值
		//首先查询cf_app，遍历所有运行中的应用
		List<CfApp> apps = new ArrayList<CfApp>();
		CfAppExample caExample = new CfAppExample();
		caExample.createCriteria().andStateEqualTo(this.APPSTATE);
		apps = caMapper.selectByExample(caExample);
		
		if(apps.size()!=0){//能查到应用才会进行循环
			
			//循环遍历每一个APP来监控其状态
			for(CfApp app:apps){
				
//				Map<String, Object> data = null;
				try {
					String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
					String urlPath = host + "/v2/apps/" + app.getUuid() + "/stats";
					String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
					Map<String, Object> stats = JsonUtil.convertJsonToMap(content);
					
					int count = 0;
					
					double mem = 0;
					double disk = 0;
					for(int i=0;i<stats.size();i++){ //循环一个App的所有实例
						
						
						Map<String, Object> instance = (Map<String, Object>) ((Map<String, Object>) stats.get(String.valueOf(i))).get("stats");
						
						if(instance == null){
							
							continue;//如果没有实例，跳出当次循环
						}
						
						//开始进行判断，如果当前使用值超过预定限额就会预警
						
						double mem_quota = Double.valueOf(String.valueOf(instance.get("mem_quota")));//内存限额
						double disk_quota = Double.valueOf(String.valueOf(instance.get("disk_quota")));//硬盘限额
						
						Map<String, Object> usage = (Map<String, Object>) instance.get("usage");
						mem = Double.valueOf(String.valueOf(usage.get("mem")));//当前内存使用量
						disk = Double.valueOf(String.valueOf(usage.get("disk")));//当前硬盘使用量
						
						double limit = 0.8;//测试值，从配置文件中读取
		                if(mem/mem_quota>=limit ||disk/disk_quota>=limit){//超过限定，提出预警
		                	
		                	count++;
		                }
					}
					if(count == stats.size()){//说明每个实例都已经超过阈值
						
						Map<String, String> data = new HashMap<String, String>();
						data.put("appname", app.getAppName());
						data.put("instanceCount", String.valueOf(stats.size()) );
						data.put("memory", String.valueOf(mem));
						data.put("disk", String.valueOf(disk));
						
					    returnList.add(data);
					}
						
					
				} catch (Exception e) {
					if (e instanceof CloudFoundryApiException && ((CloudFoundryApiException) e).getErrorCode() == 400) {
						return null;
					} else {
						throw e;
					}
				}

			
			}// for(CfApp app:apps)
			
			//所有循环结束，发送预警邮件
			String htmlText = "<b> 管理员您好：</b>"+
					"<font size =\"5\" face=\"arial\" >中实例占用资源已经超过阈值，提出预警</font>";
			for(Map<String, String> map:returnList){
				
				htmlText = htmlText +"</br>应用名称："+map.get("appname")+"  实例个数："+map.get("instanceCount")+"</br>";
			}
			
			//获取 邮箱
			MailUtil.send(htmlText, "应用预警", "394564827@qq.com");
		}
		
			
	
	//	return ExtJSResponse.successResWithMap(returnList);
        return returnList;
	}

}
